// Copyright 2021 Datafuse Labs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[derive(serde::Serialize, serde::Deserialize, Copy, Clone, Debug, PartialEq, Eq)]
pub struct ParquetReadOptions {
    /// Prune row groups before reading. Require Chunk level statistics.
    /// Filter row groups don't need to read.
    prune_row_groups: bool,
    /// Prune pages before reading. Require Page level statistics.
    /// Filter rows don't need to read.
    prune_pages: bool,
    /// If use prewhere filter.
    do_prewhere: bool,
    /// If push down bitmap generated by prewhere reader to remain reader.
    /// If true, when remain reader deserializing,
    /// it will skip part of decompression and decoding according to the bitmap.
    ///
    /// Notice:
    ///
    /// - `push_down_bitmap` and  `prune_pages` are exclusive. (`push_down_bitmap && prune_pages == false`)
    /// - If `push_down_bitmap` is true, `do_prewhere` should be true, too.
    push_down_bitmap: bool,
    // /// If refresh the file meta data cache.
    // refresh_meta_cache: bool,
}

impl ParquetReadOptions {
    #[inline]
    pub fn with_prune_row_groups(mut self, v: bool) -> Self {
        self.prune_row_groups = v;
        self
    }

    #[inline]
    pub fn with_prune_pages(mut self, v: bool) -> Self {
        self.prune_pages = v;
        self.push_down_bitmap = self.push_down_bitmap && !v;
        self
    }

    #[inline]
    pub fn with_push_down_bitmap(mut self, v: bool) -> Self {
        self.push_down_bitmap = v;
        self.do_prewhere = v;
        self.prune_pages = self.prune_pages && !v;
        self
    }

    #[inline]
    pub fn with_do_prewhere(mut self, v: bool) -> Self {
        self.do_prewhere = v;
        self
    }

    // #[inline]
    // pub fn with_refresh_meta_cache(mut self, v: bool) -> Self {
    //     self.refresh_meta_cache = v;
    //     self
    // }

    #[inline]
    pub fn prune_row_groups(&self) -> bool {
        self.prune_row_groups
    }

    #[inline]
    pub fn prune_pages(&self) -> bool {
        self.prune_pages
    }

    #[inline]
    pub fn push_down_bitmap(&self) -> bool {
        self.push_down_bitmap
    }

    #[inline]
    pub fn do_prewhere(&self) -> bool {
        self.do_prewhere
    }

    // #[inline]
    // pub fn refresh_meta_cache(&self) -> bool {
    //     self.refresh_meta_cache
    // }
}

impl Default for ParquetReadOptions {
    fn default() -> Self {
        ParquetReadOptions {
            do_prewhere: true,
            prune_row_groups: true,
            prune_pages: true,
            push_down_bitmap: false,
            // refresh_meta_cache: false,
        }
    }
}
